#include "KMNetClient.h"

const unsigned int kMinimumPacketSize = 2;

KMNetClient::KMNetClient():
    mPeer(0), mHost(0)
{
    //ctor
}

KMNetClient::~KMNetClient()
{
    //dtor
}

bool KMNetClient::connectToServer(const std::string &address,unsigned int port)
{
    ENetAddress enetAddress;
    enet_address_set_host(&enetAddress, address.c_str());
    enetAddress.port = port;

    mHost = enet_host_create(NULL, 1, 0, 0, 0);

    if (!mHost) return false;

    mPeer = enet_host_connect(mHost, &enetAddress, 1, 0);

    ENetEvent event;
    if (enet_host_service(mHost, &event, 10000) <= 0 ||
        event.type != ENET_EVENT_TYPE_CONNECT)
    {
        disconnect();
        return false;
    }
    return (mPeer != 0);

}

void KMNetClient::disconnect()
{
    if (mPeer)
        enet_peer_disconnect(mPeer, 0);
    if (mHost)
        enet_host_flush(mHost);
    if (mPeer)
        enet_peer_reset(mPeer);
    if (mHost)
        enet_host_destroy(mHost);

    mPeer = 0;
    mHost = 0;
}

bool KMNetClient::isConnected() const
{
    return (mPeer && (mPeer->state == ENET_PEER_STATE_CONNECTED));
}

void KMNetClient::send(const KMNetMsgOut &msg, bool reliable,
          unsigned char channel)
{
    if (!mPeer) {
        return;
    }

    ENetPacket *packet;
    packet = enet_packet_create(msg.getData(),
                                msg.getLength(),
                                reliable ? ENET_PACKET_FLAG_RELIABLE : 0);

    if (packet)
        enet_peer_send(mPeer, channel, packet);
}

void KMNetClient::update()
{
    ENetEvent event;
    while (enet_host_service(mHost, &event, 0) > 0)
    {
        switch (event.type)
        {
            case ENET_EVENT_TYPE_RECEIVE:
            {
                if (event.packet->dataLength >= kMinimumPacketSize)
                {
                    KMNetMsgIn msg((char *)event.packet->data,
                                  event.packet->dataLength);
                    processMessageFromServer(msg);
                }
                enet_packet_destroy(event.packet);
                break;
            }
            default:
                break;
        }
    }
}
